package com.pmgames.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.pmgames.vo.Content;
import com.pmgames.vo.GameObject;
import com.pmgames.vo.Course;
import com.pmgames.vo.Relation;
import com.pmgames.vo.User;

public class PmgamesDao extends HibernateDaoSupport implements IPmgamesDao {


	private static final int EASY = 5;
	private static final int MEDIUM = 9;
	private static final int HARD = 15;
	
	public PmgamesDao() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public GameObject createGame(GameObject game) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String createSubject(Course subject) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public User createUser(String username, String password, String name, String type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void deleteGame(int id) {
		// TODO Auto-generated method stub

	}

	@Override
	public void deleteSubject(String code) {
		// TODO Auto-generated method stub

	}

	@Override
	public void deleteUser(String username) {
		// TODO Auto-generated method stub

	}

	@Override
	public GameObject editGame(int id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SuppressWarnings("unchecked")
	public GameObject loadGame(int id) {
		DetachedCriteria criteria =
			DetachedCriteria.forClass(GameObject.class)
				.add(Restrictions.eq("id", id));
			Collection<GameObject> game = getHibernateTemplate().
				findByCriteria(criteria, 0, 1);
			if(game.size() == 0)
				return null;
			else
				return game.iterator().next();
	}

	@Override
	@SuppressWarnings("unchecked")
	public User logIn(String username, String password) {
		DetachedCriteria criteria =
			DetachedCriteria.forClass(User.class)
				.add(Restrictions.eq("userName", username))
				.add(Restrictions.eq("password", password));
			Collection<User> user = getHibernateTemplate().
				findByCriteria(criteria, 0, 1);
			if(user.size() == 0)
				return null;
			else
				return user.iterator().next();
	}

	@Override
	public Content getWord(GameObject game) {
		DetachedCriteria criteria =
			DetachedCriteria.forClass(Content.class)
			.add(Restrictions.conjunction()
				.add(Restrictions.eq("course", game.getCourse()))
				.add(Restrictions.eq("module", game.getModule())));
		
			Collection<Content> wordList = getHibernateTemplate().
				findByCriteria(criteria, 0, Integer.MAX_VALUE);
			
			if(wordList.size() == 0)
				return null;
			else
			{
				Random rand = new Random();
				int index = rand.nextInt(wordList.size());
				Content word = null;
				Iterator<Content> itr = wordList.iterator();
				while(index >= 0)
				{
					index--;
					word = itr.next();					
				}
				return word;
			}
	}

	@Override
	public Relation getRelation(Content word) {
		DetachedCriteria criteria =
			DetachedCriteria.forClass(Relation.class)
				.add(Restrictions.eq("sourceId", word));
		
			List<Relation> relationList = getHibernateTemplate().
				findByCriteria(criteria, 0, Integer.MAX_VALUE);
			if(relationList.size() == 0)
				return null;
			else
			{
				Random rand = new Random();
				int index = rand.nextInt(relationList.size());
				Relation relation = null;
				Iterator<Relation> itr = relationList.iterator();
				while(index >= 0)
				{
					index--;
					relation = itr.next();					
				}
				return relation;
			}
	}

	@Override
	public List<Relation> getRelations(GameObject game, List<Content> wordList) {
		List<Relation> relationList = new ArrayList();
		Iterator<Content> itr = wordList.iterator();
		while(itr.hasNext())
		{
			Relation rel = getRelation(itr.next());
			if(rel != null)
			{
				relationList.add(rel);
			}
		}
		if(relationList.size() == 0)
			return null;
		else
		{		
			Collections.shuffle(relationList);
			if(game.getLevel().equalsIgnoreCase("Easy"))
			{
				return relationList.subList(0, EASY);
			}
			else
			{
				if(game.getLevel().equalsIgnoreCase("Medium"))
				{
					return relationList.subList(0, MEDIUM);
				}
				else
				{
					if(game.getLevel().equalsIgnoreCase("Hard"))
					{
						return relationList.subList(0, HARD);
					}
				}
			}
		}
		return null;
	}
	
	
	@Override
	public List<Content> getWords(GameObject game) {
		DetachedCriteria criteria =
			DetachedCriteria.forClass(Content.class)
			.add(Restrictions.conjunction()
				.add(Restrictions.eq("course", game.getCourse()))
				.add(Restrictions.eq("module", game.getModule())));
		
			List<Content> wordList = getHibernateTemplate().
				findByCriteria(criteria, 0, Integer.MAX_VALUE);
			
			if(wordList.size() == 0)
				return null;
			else
			{				
				return wordList;
			}
	}

}
